package com.wzw.springboot.principle.use.security.infrastructure.provider;

import com.wzw.springboot.principle.use.security.enums.AuthenticationEnum;
import com.wzw.springboot.principle.use.security.manage.RbacManager;
import com.wzw.springboot.principle.use.thirdparty.loginauth.ThirdPartyUser;
import com.wzw.springboot.principle.use.thirdparty.loginauth.UserAuthService;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;

/**
 * @author Wangzhiwen
 */
public class ThirdPartyAuthenticationProvider extends AbstractGeneralAuthenticationProvider<ThirdPartyAuthenticationToken> {

    private final RbacManager rbacManager;

    private final UserAuthService userAuthService;

    public ThirdPartyAuthenticationProvider(RbacManager rbacManager, UserAuthService userAuthService) {
        this.rbacManager = rbacManager;
        this.userAuthService = userAuthService;
    }

    @Override
    protected AuthenticationEnum getEnum() {
        return AuthenticationEnum.THIRD_PARTY;
    }

    @Override
    protected Authentication createSuccessAuthentication(Object principal, Authentication authentication, UserDetails user) {
        ThirdPartyAuthenticationToken thirdPartyAuthenticationToken = new ThirdPartyAuthenticationToken(user, authentication.getCredentials(), user.getAuthorities());
        thirdPartyAuthenticationToken.setDetails(authentication.getDetails());
        return thirdPartyAuthenticationToken;
    }

    @Override
    protected UserDetails retrieveUser(String type, ThirdPartyAuthenticationToken authentication) throws AuthenticationException {
        ThirdPartyUser thirdPartyUser = userAuthService.userAuth(String.valueOf(authentication.getPrincipal()), String.valueOf(authentication.getCredentials()), authentication.getTerminal());
        return rbacManager.getSecurityUserByThirdPartyUser(thirdPartyUser);
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return ThirdPartyAuthenticationToken.class.isAssignableFrom(authentication);
    }
}
